﻿using Domain.Entitys.DB;
using Domain.Entitys.Pinv;
using Domain.IRepositorys.Pinv;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;

namespace EFCore.Repositorys.Pinv
{
    public class PuRepository : IPuRepository
    {
        private readonly MyDbContext myDbContext;

        public PuRepository(MyDbContext myDbContext)
        {
            this.myDbContext = myDbContext;
        }
        /// <summary>
        /// 根据条件查询采购退货信息
        /// </summary>
        /// <param name="Vendor_name"></param>
        /// <param name="Purret_code"></param>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Pu_details_Order> GetPuFyWhereSelect(string Vendor_name, string Purret_code, int currentPage, int pageSize)
        {
            IQueryable<Pinv_purret> query = myDbContext.Pinv_purret.Where(d => d.Del_flag == '0').Include(d => d.Details).OrderByDescending(d => d.Create_time);;// 确保加载 Details 导航属性
            if (!string.IsNullOrEmpty(Vendor_name))
            {
                query = query.Where(d => d.Vendor_code.Contains(Vendor_name) || d.Vendor_name.Contains(Vendor_name));
            }
            if (!string.IsNullOrEmpty(Purret_code))
            {
                query = query.Where(d => d.Purret_code.Contains(Purret_code)||d.Po_code.Contains(Purret_code));
            }
            var allData = query.ToList();//先查询所有数据到内存
            var groupData = allData.GroupBy(d => d.Purret_id).Select(d=>d.OrderByDescending(d=>d.Create_time).First()).ToList();//在内存中按 Po_id 分组，并取 Create_time 最大的记录

            var pagedData = groupData.Skip((currentPage - 1)*pageSize).Take(pageSize).Select(d=> new Pu_details_Order
            {
                Purret_id = d.Purret_id,
                Po_id = d.Po_id,
                Purret_code = d.Purret_code,
                Vendor_name = d.Vendor_name,
                Vendor_code = d.Vendor_code,
                Po_code = d.Po_code,
                Po_name = d.Po_name,
                Purret_returntime = d.Purret_returntime,
                Purret_returncause = d.Purret_returncause,
                Pu_state = d.Pu_state,
                Pu_audit = d.Pu_audit,
                Pu_audit_by = d.Pu_audit_by,
                Pu_audit_time = d.Pu_audit_time,
                Pu_audit_remark = d.Pu_audit_remark,
                Remark = d.Remark,
                Create_by = d.Create_by,
                Create_time = d.Create_time,
                Update_by = d.Update_by,
                Update_time = d.Update_time,
                Del_flag = d.Del_flag,
                Warehouse_code = d.Warehouse_code,
                Details = d.Details.Select(d=> new Pu_details_Order.details
                {
                    Podet_id = d.Podet_id,
                    Purret_id = d.Purret_id,
                    Po_code = d.Po_code,
                    Pro_name = d.Pro_name,
                    Pro_code = d.Pro_code,
                    Pro_brand = d.Pro_brand,
                    Pro_model = d.Pro_model,
                    Unitmeas_id = d.Unitmeas_id,
                    Po_number = d.Po_number,
                    Podet_inbound_quantity = d.Podet_inbound_quantity,
                    Podet_notstocked = d.Podet_notstocked,
                    Podet_retqty = d.Podet_retqty,
                    Number_returns = d.Number_returns,
                }).ToList()
            }).ToList();
            return pagedData;
        }
        /// <summary>
        /// 根据条件查询采购退货总条数
        /// </summary>
        /// <param name="Vendor_name"></param>
        /// <param name="Purret_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public int GetPuWhereCount(string Vendor_name, string Purret_code)
        {
            IQueryable<Pinv_purret> query = myDbContext.Pinv_purret.Where(d => d.Del_flag == '0');
            if (!string.IsNullOrEmpty(Vendor_name))
            {
                query = query.Where(d => d.Vendor_code.Contains(Vendor_name) || d.Vendor_name.Contains(Vendor_name));
            }
            if (!string.IsNullOrEmpty(Purret_code))
            {
                query = query.Where(d => d.Purret_code.Contains(Purret_code)|| d.Po_code.Contains(Purret_code));
            }
            return query.Count();
        }
        /// <summary>
        /// 添加采购退货订单
        /// </summary>
        /// <param name="pinv_Purret"></param>
        /// <param name="pinv_Podets"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> PostPuAdd(Pinv_purret pinv_Purret, List<Pinv_podet> pinv_Podets)
        {
            using var transaction = await myDbContext.Database.BeginTransactionAsync();
            try
            {
                // 1. 添加退货主表
                await myDbContext.AddAsync(pinv_Purret);
                await myDbContext.SaveChangesAsync();

                // 2. 设置明细关联ID并添加明细
                foreach (var pinv in pinv_Podets)
                {
                    pinv.Purret_id = pinv_Purret.Purret_id;
                    var detail = myDbContext.pinv_details.FirstOrDefault(d => d.Po_code == pinv.Po_code);
                    pinv.Number_returns = detail?.Podet_retqty ?? 0;
                }
                await myDbContext.Pinv_podet.AddRangeAsync(pinv_Podets);
                await myDbContext.SaveChangesAsync();

                // 新增逻辑：查询pinv_po和pinv_details
                var pinvPo = await myDbContext.Pinv_Po
                    .FirstOrDefaultAsync(p => p.Po_Id == pinv_Purret.Po_id);

                if (pinvPo != null)
                {
                    // 获取所有明细的details_storage状态
                    var details = await myDbContext.pinv_details
                        .Where(d => d.Po_Id == pinvPo.Po_Id)
                        .ToDictionaryAsync(d => d.Pro_code, d => d.Details_storage);

                    // 查询pinv_pb数据
                    var pinvPb = await myDbContext.pinv_Pb
                        .FirstOrDefaultAsync(p => p.Po_id == pinvPo.Po_Id);

                    // 3. 更新库存中的待退货数量（仅更新details_storage不等于0的记录）
                    foreach (var detail in pinv_Podets)
                    {
                        // 检查当前产品的details_storage是否不等于0
                        if (details.TryGetValue(detail.Pro_code, out var storage) && storage != 0)
                        {
                            // 查询所有匹配的库存记录（增加pb_code条件）
                            var stocks = await myDbContext.inv_stock
                                .Where(s => s.pro_code == detail.Pro_code &&
                                           s.Warehouse_Code == pinv_Purret.Warehouse_code &&
                                           (pinvPb == null || s.stock_entry_no == pinvPb.Pb_code))
                                .ToListAsync();

                            // 检查库存记录数量
                            if (stocks.Count == 0)
                            {
                                //throw new Exception($"库存记录不存在: 产品编码 {detail.Pro_code}");//未入库退货
                            }
                            else if (stocks.Count > 1)
                            {
                                throw new Exception($"存在多条库存记录: 产品编码 {detail.Pro_code}，请检查库存唯一性");
                            }
                            else
                            {
                                // 获取唯一库存记录
                                var stock = stocks.First();

                                // 更新待退货数量
                                stock.Stock_planned_outbound_qty += detail.Podet_retqty;
                            }
                        }
                    }
                }

                // 4. 保存所有更改
                await myDbContext.SaveChangesAsync();
                await transaction.CommitAsync();
                return 1;
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                // 记录日志或处理异常
                throw new DbUpdateException("采购退货单添加失败，已回滚", ex);
            }
        }

        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="pinv_Purret"></param>
        /// <param name="pinv_Podets"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> PutPuAudit(Pinv_purret pinv_Purret, List<Pinv_podet> pinv_Podets)
        {
            using (var transaction = myDbContext.Database.BeginTransaction())
            {
                try
                {
                    // 0. 优先处理审核逻辑
                    var purret = myDbContext.Pinv_purret.Find(pinv_Purret.Purret_id);
                    purret.Pu_audit = pinv_Purret.Pu_audit;
                    purret.Pu_audit_by = pinv_Purret.Pu_audit_by;
                    purret.Pu_audit_time = pinv_Purret.Pu_audit_time;
                    purret.Pu_audit_remark = pinv_Purret.Pu_audit_remark;

                    // 1. 批量更新 pinv_Podets（先更新内存中的实体）
                    var detailIds = pinv_Podets.Select(d => d.Podet_id).ToList();
                    var existingDetails = myDbContext.Pinv_podet
                        .Where(d => detailIds.Contains(d.Podet_id))
                        .ToDictionary(d => d.Podet_id);

                    foreach (var detail in pinv_Podets)
                    {
                        if (existingDetails.TryGetValue(detail.Podet_id, out var existing))
                        {
                            existing.Number_returns += detail.Podet_retqty;
                            existing.Podet_retqty = 0;
                        }
                    }

                    // 2. 更新 Pinv_purret 状态（使用更新后的内存值）
                    var existingPurret = myDbContext.Pinv_purret.Find(pinv_Purret.Purret_id);
                    if (existingPurret != null)
                    {
                        bool hasNonZeroReturns = existingDetails.Values
                            .Where(d => d.Purret_id == pinv_Purret.Purret_id)
                            .Any(d => d.Podet_retqty != 0);

                        existingPurret.Pu_state = hasNonZeroReturns ? '1' : '0';
                    }

                    // 更新 pinv_details 表中的 Podet_retqty
                    var poCodes = pinv_Podets.Select(d => d.Po_code).Distinct().ToList();

                    // 查询关联的Pinv_Po记录
                    var relatedPo = myDbContext.Pinv_Po
                        .Where(p => poCodes.Contains(p.Po_Code))
                        .ToList();

                    // 查询关联的pinv_details记录
                    var relatedDetails = myDbContext.pinv_details
                        .Where(d => poCodes.Contains(d.Po_code))
                        .ToList();

                    foreach (var detail in pinv_Podets)
                    {
                        if (relatedPo.Any(p => p.Po_Code == detail.Po_code))
                        {
                            var relatedDetail = relatedDetails.FirstOrDefault(d =>
                                d.Po_code == detail.Po_code &&
                                d.Pro_code == detail.Pro_code);

                            if (relatedDetail != null)
                            {
                                relatedDetail.Podet_retqty += detail.Podet_retqty;
                            }
                        }
                    }

                    // 检查是否所有pinv_details的po_number等于podet_retqty
                    bool allMatch = relatedDetails.All(d => d.Po_number == d.Podet_retqty);
                    if (allMatch)
                    {
                        foreach (var po in relatedPo)
                        {
                            po.Po_State = 9;//全部退货
                        }
                    }
                    else
                    {
                        // 2. 新增逻辑：检查是否所有 details_storage 都等于 Podet_retqty
                        bool allStorageMatch = false; // 默认全部匹配
                        bool allStorageMatchs = false;//不匹配
                        bool allStorageMatchss = false;//不匹配

                        foreach (var detail in pinv_Podets)
                        {
                            // 通过 Po_code 查询 pinv_po
                            var relatedPoForDetail = myDbContext.Pinv_Po
                                .FirstOrDefault(p => p.Po_Code == detail.Po_code);

                            if (relatedPoForDetail != null)
                            {
                                // 通过 Po_Id 查询 pinv_details
                                var detailsForPo = myDbContext.pinv_details
                                    .Where(d => d.Po_Id == relatedPoForDetail.Po_Id &&
                                           d.Pro_code == detail.Pro_code)
                                    .ToList();

                                // 检查是否所有 details_storage == Podet_retqty
                                foreach (var storageDetail in detailsForPo)
                                {
                                    if (storageDetail.Details_storage == detail.Podet_retqty)
                                    {
                                        allStorageMatch = true;
                                        break; // 只要有一个不匹配，就跳出循环
                                    }else if(storageDetail.Details_storage > detail.Podet_retqty){
                                        allStorageMatchs = true;
                                        break;
                                    }else if(storageDetail.Details_storage < detail.Podet_retqty)
                                    {
                                        allStorageMatchss = true;
                                        break;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }

                        // 如果全部匹配，则设置 Po_State = 8
                        if (allStorageMatch)
                        {
                            foreach (var po in relatedPo)
                            {
                                po.Po_State = 8;//完全退货
                            }
                        }
                        if (allStorageMatchs)
                        {
                            foreach (var po in relatedPo)
                            {
                                po.Po_State = 7;//部分退货
                            }
                        }
                        if (allStorageMatchss)
                        {
                            foreach (var po in relatedPo)
                            {
                                po.Po_State = 6;//超额退货
                            }
                        }
                    }

                    // 3. 处理库存 - 减少库存数量
                    foreach (var purretDetail in pinv_Podets)
                    {
                        if (purretDetail.Podet_retqty <= 0) continue;

                        var product = myDbContext.Db_Product
                            .FirstOrDefault(p => p.Pro_code == purretDetail.Pro_code);

                        if (product == null)
                        {
                            throw new Exception($"产品不存在: {purretDetail.Pro_code}");
                        }
                        else
                        {
                            var purrets = myDbContext.Pinv_purret.FirstOrDefault(d => d.Purret_id == purretDetail.Purret_id);

                            // 通过Pinv_purret获取Po_Id来查询Pinv_pb
                            var pinvPb = purrets != null
                                ? myDbContext.pinv_Pb.FirstOrDefault(p => p.Po_id == purrets.Po_id)
                                : null;

                            // 查询库存记录（增加pb_code条件）
                            var stock = myDbContext.inv_stock
                                .FirstOrDefault(s =>
                                    s.pro_code == purretDetail.Pro_code &&
                                    s.Warehouse_Code == purrets.Warehouse_code &&
                                    (pinvPb == null || s.stock_entry_no == pinvPb.Pb_code));

                            if (stock == null)
                            {
                                //throw new Exception($"库存记录不存在: 产品编码 {purretDetail.Pro_code}, 仓库编码 {purret.Warehouse_code}");
                            }
                            else if (stock.stock_numder < purretDetail.Podet_inbound_quantity)
                            {
                                //throw new Exception($"库存不足: 产品编码 {purretDetail.Pro_code}, 当前库存 {stock.stock_numder}, 退货数量 {purretDetail.Number_returns}");
                                return 5;
                            }
                            else if (stock.stock_numder < purretDetail.Podet_retqty)
                            {
                                //throw new Exception($"库存不足: 产品编码 {purretDetail.Pro_code}, 当前库存 {stock.stock_numder}, 退货数量 {purretDetail.Number_returns}");
                                stock.stock_numder = 0;
                                stock.Stock_planned_outbound_qty -= purretDetail.Podet_retqty;
                            }
                            else
                            {
                                stock.stock_numder -= purretDetail.Podet_retqty;
                                stock.Stock_planned_outbound_qty -= purretDetail.Podet_retqty;
                            }
                        }
                    }

                    await myDbContext.SaveChangesAsync();
                    transaction.Commit();
                    return 1;
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw ex;
                }
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="pinv_Purret"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> PutPuDelete(Pinv_purret pinv_Purret)
        {
            Pinv_purret pu = await myDbContext.Pinv_purret.FindAsync(pinv_Purret.Purret_id);
            pu.Del_flag = pinv_Purret.Del_flag;
            return await myDbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="pinv_Purret"></param>
        /// <param name="pinv_Podets"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> PutPuUpdate(Pinv_purret pinv_Purret, List<Pinv_podet> pinv_Podets)
        {
            using var transaction = await myDbContext.Database.BeginTransactionAsync();
            try
            {
                // 1. 更新主表信息
                var pu = await myDbContext.Pinv_purret.FirstOrDefaultAsync(d => d.Purret_id == pinv_Purret.Purret_id);
                if (pu == null) return 0;

                pu.Update_by = pinv_Purret.Update_by;
                pu.Update_time = pinv_Purret.Update_time;
                pu.Warehouse_code = pinv_Purret.Warehouse_code;
                pu.Purret_returncause = pinv_Purret.Purret_returncause;
                pu.Purret_returntime = pinv_Purret.Purret_returntime;
                myDbContext.Update(pu);
                await myDbContext.SaveChangesAsync();

                // 2. 获取旧明细数据
                var oldDetails = await myDbContext.Pinv_podet
                    .Where(d => d.Purret_id == pu.Purret_id)
                    .AsNoTracking()
                    .ToListAsync();

                // 3. 更新明细并计算库存变化
                foreach (var newItem in pinv_Podets)
                {
                    var oldItem = oldDetails.FirstOrDefault(old => old.Podet_id == newItem.Podet_id);

                    if (oldItem != null && IsModified(oldItem, newItem))
                    {
                        var existingEntity = await myDbContext.Pinv_podet.FindAsync(newItem.Podet_id);

                        // 计算数量变化差值
                        decimal quantityDiff = newItem.Podet_retqty - oldItem.Podet_retqty;

                        // 更新明细数量
                        existingEntity.Podet_retqty = newItem.Podet_retqty;
                        myDbContext.Entry(existingEntity).Property(x => x.Podet_retqty).IsModified = true;

                        // 更新库存待出库数量
                        var stock = await myDbContext.inv_stock
                            .FirstOrDefaultAsync(s => s.pro_code == existingEntity.Pro_code
                                                  && s.Warehouse_Code == pu.Warehouse_code);

                        if (stock == null)
                        {
                            throw new Exception($"库存记录不存在: 产品编码 {newItem.Pro_code}");
                        }

                        stock.Stock_planned_outbound_qty += quantityDiff;
                    }
                }

                // 4. 保存所有更改
                await myDbContext.SaveChangesAsync();
                await transaction.CommitAsync();
                return 1;
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                // 记录日志或处理异常
                throw new DbUpdateException("采购退货单更新失败，已回滚", ex);
            }
        }
        private bool IsModified(Pinv_podet oldItem, Pinv_podet newItem)
        {
            return oldItem.Podet_retqty != newItem.Podet_retqty;
        }
    }
}
